package com.csii.test;

import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.csii.test.TLinx.TLinxMD5;
import com.csii.test.TLinx.TLinxMapUtil;
import com.csii.test.TLinx.TLinxSHA1;


/**
 * @Class: TLinxAESCoder.java
 * @Description: AES加解密类
 * @Author：caiqf
 * @Date：2016-4-12
 */
public class TLinxAESCoder {
	
	static Log log = LogFactory.getLog(TLinxAESCoder.class);
    private static String CIPHER_ALGORITHM = "AES/ECB/PKCS5Padding";
    private static String KEY_ALGORITHM = "AES";
    private static String OPEN_KEY="d5028288da844ca986d4f96e6107f04d";

    public static String decrypt(String sSrc) throws Exception {
        SecretKeySpec skeySpec = new SecretKeySpec(OPEN_KEY.getBytes("ASCII"), KEY_ALGORITHM);
        Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
        cipher.init(2, skeySpec);
        byte[] encrypted1 = hex2byte(sSrc);
        byte[] original = cipher.doFinal(encrypted1);
        return new String(original, "UTF-8");
    }

    /**
     * 
     * @param datamap
     * @param postmap
     * @param openKey   
     * @return
     * @throws Exception
     */
    public static Map encrypt(Map datamap, Map postmap) throws Exception {
    	JSONObject dataobj = JSONObject.parseObject(JSON.toJSONString(datamap));
    	String sSrc = dataobj.toString();
        log.info("====云音响通知data加密前的明文= " + sSrc);
        SecretKeySpec skeySpec = new SecretKeySpec(OPEN_KEY.getBytes("ASCII"), KEY_ALGORITHM);
        Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
        cipher.init(1, skeySpec);
        byte[] encrypted = cipher.doFinal(sSrc.getBytes("UTF-8"));
        String data = byte2hex(encrypted);
        log.info("加密后的data:"+data);
        postmap.put("data", data);
        return postmap;
    }
    
    public static void main(String[] args) throws Exception {
		Map map = new HashMap();
		map.put("test", "test");
		map.put("name", "zxj");
		map.put("age", "32");
		
		Map postMap = new HashMap();
		postMap.put("open_id", "abcdefg");
		String timestamp = new Date().getTime() / 1000 + "";    // 时间
		postMap.put("timestamp", timestamp);
		
		postMap = TLinxAESCoder.encrypt(map, postMap);
		
		String sData = TLinxAESCoder.decrypt(postMap.get("data").toString());
		
		System.out.println(sData);
		
		TLinxAESCoder.handleSign(postMap);
	}
    
    /**
     * 签名
     *
     * @param postmap
     */
    public static Map handleSign(Map postmap) {
        Map<String, String> veriDataMap = new HashMap<String, String>();

        veriDataMap.putAll(postmap);
        veriDataMap.put("open_key", OPEN_KEY);

        // 签名
        String sign = sign(veriDataMap);

        log.info("====已签名字符串= " + sign);
        postmap.put("sign", sign);
        return postmap;
    }
    
    
    /**
     * 签名
     *
     * @param postMap
     * @return
     */
    public static String sign(Map<String, String> postMap) {
        String sign = null;

        try {
            /**
             * 1 A~z排序(加上open_key)
             */
            String sortStr = sort(postMap);
            log.info("====排序后的待签名字符串= " + sortStr);
            /**
             * 2 sha1加密(小写)
             */
            String sha1 = TLinxSHA1.SHA1(sortStr).toLowerCase();
            log.info("====sha1加密后的待签名字符串= " + sha1);
            /**
             * 3 md5加密(小写)
             */
            sign = TLinxMD5.MD5Encode(sha1).toLowerCase();
        } catch (Exception e) {
            e.printStackTrace();
        }

        return sign;
    }
    
    
    /**
     * 排序
     *
     * @param paramMap
     * @return
     * @throws Exception
     */
    public static String sort(Map paramMap) throws Exception {
        String sort = "";
        TLinxMapUtil signMap = new TLinxMapUtil();
        if (paramMap != null) {
            String key;
            for (Iterator it = paramMap.keySet().iterator(); it.hasNext(); ) {
                key = (String) it.next();
                String value = ((paramMap.get(key) != null) && (!("".equals(paramMap.get(key).toString())))) ? paramMap.get(key).toString() : "";
                signMap.put(key, value);
            }
            signMap.sort();
            for (Iterator it = signMap.keySet().iterator(); it.hasNext(); ) {
                key = (String) it.next();
                sort = sort + key + "=" + signMap.get(key).toString() + "&";
            }
            if ((sort != null) && (!("".equals(sort)))) {
                sort = sort.substring(0, sort.length() - 1);
            }
        }
        return sort;
    }
    
    /**
     * 十六进制字符串转byte数组
     */
    public static byte[] hex2byte(String strhex) {
        if (strhex == null)
            return null;

        int l = strhex.length();
        if (l % 2 == 1)
            return null;

        byte[] b = new byte[l / 2];
        for (int i = 0; i != l / 2; ++i)
            b[i] = (byte) Integer.parseInt(strhex.substring(i * 2, i * 2 + 2), 16);

        return b;
    }
    
    
    /**
     * byte数组转十六进制字符串
     */
    public static String byte2hex(byte[] result) {
        StringBuffer sb = new StringBuffer(result.length * 2);
        for (int i = 0; i < result.length; i++) {
            int hight = ((result[i] >> 4) & 0x0f);
            int low = result[i] & 0x0f;
            sb.append(hight > 9 ? (char) ((hight - 10) + 'a') : (char) (hight + '0'));
            sb.append(low > 9 ? (char) ((low - 10) + 'a') : (char) (low + '0'));
        }
        return sb.toString();
    }
}
